package com.shiyi.shiyiaicodefather.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.shiyi.shiyiaicodefather.constant.UserConstant;
import com.shiyi.shiyiaicodefather.exception.BusinessException;
import com.shiyi.shiyiaicodefather.exception.ErrorCode;
import com.shiyi.shiyiaicodefather.exception.ThrowUtils;
import com.shiyi.shiyiaicodefather.model.dto.chatHistory.ChatHistoryQueryRequest;
import com.shiyi.shiyiaicodefather.model.entity.App;
import com.shiyi.shiyiaicodefather.model.entity.ChatHistory;
import com.shiyi.shiyiaicodefather.mapper.ChatHistoryMapper;
import com.shiyi.shiyiaicodefather.model.entity.User;
import com.shiyi.shiyiaicodefather.model.enums.ChatHistoryMessageTypeEnum;
import com.shiyi.shiyiaicodefather.model.message.ToolExecutedMessage;
import com.shiyi.shiyiaicodefather.model.message.ToolRequestMessage;
import com.shiyi.shiyiaicodefather.service.AppService;
import com.shiyi.shiyiaicodefather.service.ChatHistoryService;
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ToolExecutionResultMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 对话历史 服务层实现。
 *
 * @author 十一
 */
@Service
@Slf4j
public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryMapper, ChatHistory>  implements ChatHistoryService{

  @Resource
  @Lazy
  private AppService appService;

  @Override
  public boolean addChatMessage(Long appId, String message, String messageType, Long userId) {
    ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
    ThrowUtils.throwIf(StrUtil.isBlank(message), ErrorCode.PARAMS_ERROR, "消息内容不能为空");
    ThrowUtils.throwIf(StrUtil.isBlank(messageType), ErrorCode.PARAMS_ERROR, "消息类型不能为空");
    ThrowUtils.throwIf(userId == null || userId <= 0, ErrorCode.PARAMS_ERROR, "用户ID不能为空");
    // 验证消息类型是否有效
    ChatHistoryMessageTypeEnum messageTypeEnum = ChatHistoryMessageTypeEnum.getEnumByValue(messageType);
    ThrowUtils.throwIf(messageTypeEnum == null, ErrorCode.PARAMS_ERROR, "不支持的消息类型: " + messageType);
    String category = null;
    if (messageTypeEnum.getValue().equals(ChatHistoryMessageTypeEnum.USER.getValue()) ||
        messageTypeEnum.getValue().equals(ChatHistoryMessageTypeEnum.AI.getValue())) {
      category = "display";
    }else{
      category = "cache";
    }
    ChatHistory chatHistory = ChatHistory.builder()
      .appId(appId)
      .message(message)
      .messageType(messageType)
      .userId(userId)
      .category(category)
      .build();
    return this.save(chatHistory);
  }

  @Override
  public boolean addChatMessageBatch(List<ChatHistory> chatHistoryList) {
    ThrowUtils.throwIf(CollUtil.isEmpty(chatHistoryList),ErrorCode.PARAMS_ERROR, "消息列表不能为空");
    List<ChatHistory> chatHistories = chatHistoryList.stream().filter(item -> {
      ChatHistoryMessageTypeEnum messageTypeEnum = ChatHistoryMessageTypeEnum.getEnumByValue(item.getMessageType());
      if (messageTypeEnum == null) {
        log.error("不支持的消息类型: {}", item.getMessageType());
        return false;
      }
      return true;
    }).toList();
    if (CollUtil.isEmpty(chatHistories)) {
      return false;
    }
    return this.saveBatch(chatHistories);
  }


  @Override
  public void deleteByAppId(Long appId) {
    ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
    QueryWrapper queryWrapper = QueryWrapper.create()
      .eq("appId", appId);
    this.remove(queryWrapper);
  }


  @Override
  public Page<ChatHistory> listAppChatHistoryByPage(Long appId, int pageSize,
                                                    LocalDateTime lastCreateTime,
                                                    User loginUser) {
    ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
    ThrowUtils.throwIf(pageSize <= 0 || pageSize > 50, ErrorCode.PARAMS_ERROR, "页面大小必须在1-50之间");
    ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);
    // 验证权限：只有应用创建者和管理员可以查看
    App app = appService.getById(appId);
    ThrowUtils.throwIf(app == null, ErrorCode.NOT_FOUND_ERROR, "应用不存在");
    boolean isAdmin = UserConstant.ADMIN_ROLE.equals(loginUser.getUserRole());
    boolean isCreator = app.getUserId().equals(loginUser.getId());
    ThrowUtils.throwIf(!isAdmin && !isCreator, ErrorCode.NO_AUTH_ERROR, "无权查看该应用的对话历史");
    // 构建查询条件
    ChatHistoryQueryRequest queryRequest = new ChatHistoryQueryRequest();
    queryRequest.setAppId(appId);
    queryRequest.setCategory("display");
    queryRequest.setLastCreateTime(lastCreateTime);
    QueryWrapper queryWrapper = this.getQueryWrapper(queryRequest);
    // 查询数据
    return this.page(Page.of(1, pageSize), queryWrapper);
  }


  /**
   * 加载历史对话到记忆中
   *
   * @param appId
   * @param chatMemory
   * @param maxCount
   */
  @Override
  public void loadChatHistoryToMemory(Long appId, MessageWindowChatMemory chatMemory, int maxCount){
    QueryWrapper queryWrapper = QueryWrapper.create()
      .eq(ChatHistory::getAppId, appId)
      .orderBy(ChatHistory::getCreateTime, false)
      .limit(1,maxCount);
    List<ChatHistory> chatHistories = this.list(queryWrapper);
    if (CollUtil.isEmpty(chatHistories)) {
      return;
    }

    chatHistories = CollUtil.reverseNew(chatHistories);
    int loadCount = 0;
    chatMemory.clear();
    for (ChatHistory chatHistory : chatHistories) {
      ChatHistoryMessageTypeEnum messageTypeEnum = ChatHistoryMessageTypeEnum.getEnumByValue(chatHistory.getMessageType());
      switch (messageTypeEnum){
        case USER:
          chatMemory.add(UserMessage.from(chatHistory.getMessage()));
          loadCount++;
          break;
        case AI:
          chatMemory.add(AiMessage.from(chatHistory.getMessage()));
          loadCount++;
          break;
        case TOOL_EXECUTION_REQUEST:
          ToolRequestMessage toolRequestMessage = JSONUtil.toBean(chatHistory.getMessage(), ToolRequestMessage.class);
          ToolExecutionRequest toolExecutionRequest = ToolExecutionRequest.builder()
            .id(toolRequestMessage.getId())
            .name(toolRequestMessage.getName())
            .arguments(toolRequestMessage.getArguments())
            .build();
          if (StrUtil.isNotBlank(toolRequestMessage.getText())) {
            chatMemory.add(AiMessage.from(toolRequestMessage.getText(),List.of(toolExecutionRequest)));
          }else{
            chatMemory.add(AiMessage.from(List.of(toolExecutionRequest)));
          }
          loadCount++;
          break;
        case TOOL_EXECUTION_RESULT:
          ToolExecutedMessage toolExecutedMessage = JSONUtil.toBean(chatHistory.getMessage(), ToolExecutedMessage.class);
          String id = toolExecutedMessage.getId();
          String name = toolExecutedMessage.getName();
          String arguments = toolExecutedMessage.getArguments();
          chatMemory.add(ToolExecutionResultMessage.from(id, name, arguments));
          loadCount++;
            break;
          case null, default:
          log.error("未知的消息类型:{}", chatHistory.getMessageType());
            break;
      }
//      if (ChatHistoryMessageTypeEnum.USER.getValue().equals() {
//        chatMemory.add(UserMessage.from(chatHistory.getMessage()));
//      }else if(ChatHistoryMessageTypeEnum.AI.getValue().equals(chatHistory.getMessageType())){
//        chatMemory.add(AiMessage.from(chatHistory.getMessage()));
//      }
      loadCount++;
    }
  }

  /**
   * 获取查询包装类
   *
   * @param chatHistoryQueryRequest
   * @return
   */
  @Override
  public QueryWrapper getQueryWrapper(ChatHistoryQueryRequest chatHistoryQueryRequest) {
    QueryWrapper queryWrapper = QueryWrapper.create();
    if (chatHistoryQueryRequest == null) {
      return queryWrapper;
    }
    Long id = chatHistoryQueryRequest.getId();
    String message = chatHistoryQueryRequest.getMessage();
    String messageType = chatHistoryQueryRequest.getMessageType();
    Long appId = chatHistoryQueryRequest.getAppId();
    Long userId = chatHistoryQueryRequest.getUserId();
    String category = chatHistoryQueryRequest.getCategory();
    LocalDateTime lastCreateTime = chatHistoryQueryRequest.getLastCreateTime();
    String sortField = chatHistoryQueryRequest.getSortField();
    String sortOrder = chatHistoryQueryRequest.getSortOrder();
    // 拼接查询条件
    queryWrapper.eq("id", id)
      .like("message", message)
      .eq("messageType", messageType)
      .eq("appId", appId)
      .eq("userId", userId)
      .eq("category",category);
    // 游标查询逻辑 - 只使用 createTime 作为游标
    if (lastCreateTime != null) {
      queryWrapper.lt("createTime", lastCreateTime);
    }
    // 排序
    if (StrUtil.isNotBlank(sortField)) {
      queryWrapper.orderBy(sortField, "ascend".equals(sortOrder));
    } else {
      // 默认按创建时间降序排列
      queryWrapper.orderBy("createTime", false);
    }
    return queryWrapper;
  }


}
